package com.reminis.exceldemo.web;

import com.reminis.exceldemo.entity.fromqf;
import com.reminis.exceldemo.entity.fromqf_download;
import com.reminis.exceldemo.service.FromqfService;
import com.reminis.exceldemo.util.ExcelUtils;
import com.reminis.exceldemo.util.LogUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@CrossOrigin("*")
@RestController
@RequestMapping("/api/test")
public class ExcelController {

    private static final Logger log = LogManager.getLogger(ExcelController.class);

    @Autowired
    private FromqfService FromqfService;

    /**
     * Excel导出功能，导出符合ERP数据格式的Excel文件
     * @param request HTTP请求对象
     * @param response HTTP响应对象，用于文件下载
     */
    @GetMapping("/exportExcel")
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) {
        log.info("=== 开始处理Excel导出请求 ===");
        
        try {
            // 获取数据库中的数据
            log.info("开始从数据库获取导出数据");
            List<fromqf_download> fromqf_download = FromqfService.douloadExcel();
            
            if (fromqf_download == null || fromqf_download.isEmpty()) {
                log.warn("没有可导出的数据");
                return;
            }
            
            log.info("获取到导出数据 {} 条", fromqf_download.size());
            
            // 日期格式化器
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-M-d");
            String fileName1 = "";
            
            // 处理每条数据的格式转换
            log.info("开始处理数据格式转换");
            int processedCount = 0;
            
            for (fromqf_download fromqf_download1 : fromqf_download) {
                try {
                    Date date = fromqf_download1.get日期();
                    log.debug("处理第 {} 条数据的日期转换 - 原始日期: {}", processedCount + 1, date);
                    
                    if (date != null) {
                        String dateString = inputFormat.format(date);
                        String format = outputFormat.format(inputFormat.parse(dateString));
                        fromqf_download1.set日期(outputFormat.parse(format));
                        log.debug("日期转换完成 - 转换后日期: {}", format);
                    }
                    
                    // 获取订单号用于文件名
                    if (fileName1.isEmpty() && fromqf_download1.get订单号() != null) {
                        fileName1 = fromqf_download1.get订单号();
                        log.info("设置导出文件名前缀为订单号: {}", fileName1);
                    }
                    
                    // 设置固定字段值
                    fromqf_download1.set客户代码("C251"); // 客户代码固定值
                    fromqf_download1.set预交日期(fromqf_download1.get日期()); // 预交日期设置为订单日期
                    fromqf_download1.set币别("RMB"); // 币种固定为RMB
                    
                    processedCount++;
                    
                } catch (ParseException e) {
                    log.error("处理第 {} 条数据时日期解析错误 - 错误信息: {}", processedCount + 1, e.getMessage(), e);
                } catch (Exception e) {
                    log.error("处理第 {} 条数据时发生异常 - 错误信息: {}", processedCount + 1, e.getMessage(), e);
                }
            }
            
            log.info("数据格式转换完成 - 成功处理 {} 条数据", processedCount);
            
            // 生成文件名
            Date currentDate = new Date();
            SimpleDateFormat fileNameFormat = new SimpleDateFormat("yyyyMMddHHmm");
            String timeStamp = fileNameFormat.format(currentDate);
            String finalFileName = fileName1 + "_" + timeStamp;
            
            log.info("生成导出文件名: {}.xlsx", finalFileName);
            
            // 执行Excel文件写入
            log.info("开始生成Excel文件并响应下载");
            ExcelUtils.writeExcel(request, response, finalFileName, fromqf_download, fromqf_download.class);
            
            log.info("=== Excel导出处理完成 ===");
            
        } catch (Exception e) {
            log.error("处理Excel导出时发生严重异常 - 错误信息: {}", e.getMessage(), e);
            // 这里可以考虑向前端返回错误信息，但由于方法返回void，需要通过response写入错误信息
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.getWriter().write("导出Excel文件时发生错误: " + e.getMessage());
            } catch (Exception writeException) {
                log.error("写入错误响应时发生异常: {}", writeException.getMessage());
            }
        }
    }

    /**
     * Excel导入功能
     * 处理前端上传的Excel文件，解析数据并保存到数据库
     * 2024年11月18日15:14:56 新增导入Excel时，校验中类是否存在数据表，不存在则返回前端提示，并返回前端，提示具体中类不存在
     * @param file 上传的Excel文件
     * @return 处理结果标志（1表示成功，0表示失败）
     */
    @PostMapping("/readExcel")
    public int readExcel(@RequestBody MultipartFile file) {
        long startTime = System.currentTimeMillis();
        log.info("=== 开始处理Excel文件上传 ===");
        
        // 参数验证
        if (file == null || file.isEmpty()) {
            log.error("Excel文件上传失败 - 文件为空或null");
            LogUtils.logBusinessOperation("Excel文件上传", startTime, System.currentTimeMillis(), 
                                        false, "文件为空或null");
            return 0;
        }
        
        // 记录文件上传详细信息
        LogUtils.logFileUpload(file, "Excel数据导入");
        
        String originalFileName = file.getOriginalFilename();
        
        try {
            // 验证文件名
            if (originalFileName == null || !originalFileName.contains(".")) {
                log.error("Excel文件名格式错误 - 文件名: {}", originalFileName);
                return 0;
            }
            
            // 提取订单号（去掉文件扩展名）
            String fileName = originalFileName.substring(0, originalFileName.indexOf("."));
            log.info("提取的订单号: {}", fileName);
            
            // 解析Excel数据
            log.info("开始解析Excel文件内容");
            List<fromqf> list = ExcelUtils.readExcel("", fromqf.class, file);
            
            if (list == null || list.isEmpty()) {
                log.warn("Excel文件解析完成，但没有获取到有效数据");
                return 0;
            }
            
            log.info("Excel文件解析完成 - 共解析到 {} 条数据记录", list.size());
            
            // 准备当前日期
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String currentDate = simpleDateFormat.format(new Date());
            log.info("设置数据日期为: {}", currentDate);
            
            // 清空数据库中的旧数据
            log.info("开始清空数据库中的旧数据");
            FromqfService.truncate();
            log.info("数据库旧数据清空完成");
            
            // 批量保存数据
            log.info("开始批量保存Excel数据到数据库");
            int successCount = 0;
            int failCount = 0;
            
            for (int i = 0; i < list.size(); i++) {
                fromqf fromqfItem = list.get(i);
                
                try {
                    // 设置订单号和日期
                    fromqfItem.set订单号(fileName);
                    fromqfItem.set日期(currentDate);
                    
                    log.debug("准备保存第 {} 条数据 - 材料编号: {}, 材料名称: {}", 
                             i + 1, fromqfItem.get材料编号(), fromqfItem.get编码());
                    
                    // 保存到数据库
                    boolean saveResult = FromqfService.save(fromqfItem);
                    
                    if (saveResult) {
                        successCount++;
                        log.debug("第 {} 条数据保存成功", i + 1);
                    } else {
                        failCount++;
                        log.warn("第 {} 条数据保存失败 - 材料编号: {}", i + 1, fromqfItem.get材料编号());
                    }
                    
                } catch (Exception e) {
                    failCount++;
                    log.error("保存第 {} 条数据时发生异常 - 材料编号: {}, 错误信息: {}", 
                             i + 1, fromqfItem.get材料编号(), e.getMessage(), e);
                }
            }
            
            log.info("批量保存完成 - 成功: {} 条, 失败: {} 条, 总计: {} 条", 
                    successCount, failCount, list.size());
            
            if (failCount > 0) {
                log.warn("存在保存失败的数据，请检查日志详情");
            }
            
            // 记录整体操作结果
            long endTime = System.currentTimeMillis();
            boolean overallSuccess = failCount == 0;
            String details = String.format("文件名: %s, 解析记录: %d, 成功保存: %d, 失败: %d", 
                                          originalFileName, list.size(), successCount, failCount);
            
            LogUtils.logBusinessOperation("Excel文件导入", startTime, endTime, overallSuccess, details);
            LogUtils.logExcelOperation("导入", originalFileName, successCount, endTime - startTime, overallSuccess);
            LogUtils.logDatabaseOperation("BATCH_INSERT", "fromqf", successCount, 
                                        String.format("批量插入Excel数据，成功%d条，失败%d条", successCount, failCount));
            
            log.info("=== Excel文件上传处理完成 ===");
            return 1; // 返回成功标志
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            String context = String.format("文件名: %s, 文件大小: %d bytes", originalFileName, file.getSize());
            
            LogUtils.logException("Excel文件导入", e, context);
            LogUtils.logBusinessOperation("Excel文件导入", startTime, endTime, false, 
                                        "处理过程中发生异常: " + e.getMessage());
            
            return 0; // 返回失败标志
        }
    }

    /**
     * 处理仓库数据并返回一个包含特定数据对象的列表
     * 这个方法主要用于模拟从仓库中获取数据并封装到fromqf对象列表中
     * 它循环生成一组数据对象，设置其属性，并将它们添加到列表中
     *
     * @return 包含模拟仓库数据的fromqf对象列表
     */
    public List<fromqf> handleRepositoryData() {
        // 创建一个fromqf对象列表，用于存储仓库数据
        List<fromqf> fromqfList = new ArrayList<>();

            fromqfList = FromqfService.getAll();

        // 返回填充好的fromqf对象列表
        return fromqfList;
    }

    /**
     * 获取前台页面的分页数据列表
     * @param page 页码（从1开始）
     * @param limit 每页显示的记录数
     * @return 包含分页数据的Map对象
     */
    @GetMapping("/getList")
    public Map<String, List<fromqf>> getList(int page, int limit) {
        log.info("接收到分页查询请求 - 页码: {}, 每页数量: {}", page, limit);
        
        try {
            // 参数验证
            if (page < 1) {
                log.warn("页码参数无效，重置为1 - 原始页码: {}", page);
                page = 1;
            }
            if (limit < 1 || limit > 1000) {
                log.warn("每页数量参数无效，重置为10 - 原始数量: {}", limit);
                limit = 10;
            }
            
            // 获取分页数据
            List<fromqf> fromqfList = FromqfService.getLimitAll(page, limit);
            
            // 构建返回结果
            Map<String, List<fromqf>> result = new HashMap<>();
            result.put("data", fromqfList);
            
            log.info("分页查询完成 - 页码: {}, 每页数量: {}, 返回记录数: {}", 
                    page, limit, fromqfList != null ? fromqfList.size() : 0);
            
            return result;
            
        } catch (Exception e) {
            log.error("分页查询时发生异常 - 页码: {}, 每页数量: {}, 错误信息: {}", 
                     page, limit, e.getMessage(), e);
            
            // 返回空结果
            Map<String, List<fromqf>> errorResult = new HashMap<>();
            errorResult.put("data", new ArrayList<>());
            return errorResult;
        }
    }

    /**
     * 获取fromqf数据总数，用于layui分页组件
     * @return JSON格式的总数信息
     */
    @RequestMapping("/getCount")
    @ResponseBody
    public String getCount() {
        log.info("接收到查询数据总数请求");
        
        try {
            int count = FromqfService.getCount();
            String result = "{\"count\":" + count + "}";
            
            log.info("查询数据总数完成 - 总数: {}", count);
            return result;
            
        } catch (Exception e) {
            log.error("查询数据总数时发生异常 - 错误信息: {}", e.getMessage(), e);
            
            // 返回错误结果
            return "{\"count\":0,\"error\":\"查询失败\"}";
        }
    }
}
